/**
 * 题目: 
 * 实现一个Promise.all
 * 
 * 描述: 
 * 1. 得到一个新的Promise，该Promise的状态取决于proms的执行
 * 2. proms是一个迭代器，包含多个Promise
 * 3. 全部Promise成功，返回的Promise才成功，数据为所有Primsise成功的数据，并且顺序时按照传入的顺序排列
 * 4. 只要有一个Promise失败，则=返回的Pormise失败，原因是第一个Promise失败的原因
 * 
 * 参考:
 * https://github.com/Sunny-117/js-challenges/issues/1
 * 
 * @param {iterator} proms 可迭代对象
 * @return {Object} 新的promise实例
*/
Promise.myAll = function(proms) {
  // 返回一个新的Promise
  return new Promise((resolve, reject) => {
    // 若传入参数为 undefined  | null | 不是迭代器(无[Symbol.iterator]方法)
    if(proms == null || typeof proms[Symbol.iterator] !== 'function') {
      throw new TypeError(`${proms} is not a iterable`)
    }
  
    proms = [...proms]
    let leng = proms.length
    
    // 处理proms传空数组
    if (leng === 0) resolve([])

    let count = 0 // 记录执行了多少个prom
    const values = [] // 记录执行prom得到的值

    proms.forEach((prom, index) => {
      Promise.resolve(prom)
        .then(res => {
          count++ // 执行成功+1
          values[index] = res // 收集成功值，不能改成values.push(res)
          if (count === leng) resolve(values) // proms全部执行完, resolve掉values
        })
        .catch(err => reject(err))
    }) 
  })
}

// // 测试1:
// try{
//   Promise.myAll(null).then(res=>console.log(res), rej=>console.log(rej))
// }catch(e){
//   console.log(e) // null is not a iterable
// }


// // 测试2:
// try{
//   Promise.myAll({}).then(res=>console.log(res), rej=>console.log(rej)); 
// }catch(e){
//   console.log(e) // [object Object] is not a iterable
// }


// // 测试3:
// Promise.myAll([]).then(
//   (res) => console.log(res), // []
//   (err) => console.log(err)
// )


// // 测试4:
// Promise.myAll([
//   Promise.resolve(1),
//   Promise.resolve(2),
//   Promise.resolve(3),
//   4,
// ]).then(
//   (res) => console.log(res), // [ 1, 2, 3, 4 ]
//   (err) => console.log(err)
// )


// // 测试5:
// Promise.myAll([
//   Promise.reject(1),
//   Promise.resolve(2),
//   Promise.resolve(3),
//   4,
// ]).then(
//   (res) => console.log(res), 
//   (err) => console.log(err) // 1
// )

// // 测试6:
// Promise.myAll([
//   Promise.resolve(1),
//   Promise.resolve(2),
//   Promise.reject(3).catch((err) => console.log(err)), //3
//   4,
// ]).then(
//   (res) => console.log(res), // reject后catch捕获到了错误，走成功，[ 1, 2, 4, undefined ]
//   (err) => console.log(err)
// )
